package com.pkk.penguin.components.validator.util;

import com.pkk.components.rpc.common.code.CommonCode;
import com.pkk.penguin.components.validator.annotation.constraint.group.BusinessMessage;
import com.pkk.penguin.components.validator.annotation.constraint.group.SystemMessage;
import com.pkk.penguin.components.validator.exception.FieldBusinessException;
import com.pkk.penguin.components.validator.exception.code.FiledCode;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description: 验证参数的工具类
 * @return:
 * @Author: peikunkun
 * @Date: 2020/4/2 0002 下午 1:34
 */
@Slf4j
public class BeanValidatorUtil {

  private static Validator validator;

  static {
    validator = Validation.buildDefaultValidatorFactory().getValidator();
  }

  /**
   * 对象的validation检查，如果有错误则抛出Exception
   *
   * @param model 待检查对象
   * @Return
   */
  public static <T> void checkModelValidation(T model) throws FieldBusinessException {
    try {
      Set<ConstraintViolation<T>> set = validator.validate(model);
      String modelName = model.getClass().getName();
      for (ConstraintViolation<T> constraintViolation : set) {
        String message = constraintViolation.getMessage();
        log.error("==>> modeleName:{} message:{}", modelName, message);
        /** 系统异常，不用给客户端提示 */
        if (constraintViolation.getConstraintDescriptor().getPayload().stream()
            .anyMatch(s -> s.isAssignableFrom(SystemMessage.class))) {
          throw new FieldBusinessException(FiledCode.FIELD_SYSTEM_ERROR);
        } else if (constraintViolation.getConstraintDescriptor().getPayload().stream()
            .anyMatch(s -> s.isAssignableFrom(BusinessMessage.class))) {
          /** 字段异常，可以给客户端提示 */
          throw new FieldBusinessException(FiledCode.FIELD_BUSINESS_ERROR, message);
        } else {
          throw new FieldBusinessException(FiledCode.FIELD_SYSTEM_ERROR);
        }
      }
    } catch (FieldBusinessException e) {
      throw e;
    } catch (Exception e) {
      throw new FieldBusinessException(CommonCode.FAIL);
    }
  }

  /**
   * 校验对象
   *
   * @param object 待校验对象
   * @param groups 待校验的组
   * @throws RuntimeException 校验不通过，则报RRException异常
   */
  public static void validateEntity(Object object, Class<?>... groups) throws RuntimeException {
    Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
    if (!constraintViolations.isEmpty()) {
      StringBuilder msg = new StringBuilder();
      for (ConstraintViolation<Object> constraint : constraintViolations) {
        msg.append(constraint.getMessage()).append("<br>");
      }
      throw new FieldBusinessException(FiledCode.FIELD_BUSINESS_ERROR, msg.toString());
    }
  }
}
